package org.jvending.provisioning.adapter;

import org.jvending.provisioning.deliverable.OtaDescriptorFile;
import org.jvending.provisioning.descriptor.media.ProductType;
import org.jvending.provisioning.descriptor.media.MediaObjectType;

import javax.provisioning.adapter.Adapter;
import javax.provisioning.adapter.AdapterContext;
import javax.provisioning.adapter.AdapterException;
import javax.provisioning.adapter.AdapterConfig;
import javax.provisioning.DescriptorFile;
import javax.provisioning.FulfillmentTask;
import javax.provisioning.BundleDescriptor;
import javax.provisioning.Deliverable;
import java.net.URL;
import java.net.URISyntaxException;
import java.io.IOException;
import java.io.ByteArrayOutputStream;
import java.io.InputStream;
import java.util.List;
import java.util.ArrayList;

public class OtaAdapter extends Adapter {
    /**
     * Default Constructor. This class is meant to be instantiated by the framework, not by the application developer.
     */
    public OtaAdapter() {
    }

    public DescriptorFile createDescriptorFile(URL url) throws AdapterException {
        if (url == null) throw new AdapterException("JV-1200-001: MIDP", "URL can not be null");
        AdapterContext adapterContext = adapterConfig.getAdapterContext();
        //sanity check
        if (adapterContext == null)
            throw new AdapterException("MIDP", "JV-1200-002: SEVERE exception: AdapterContext is null");

        //spec (7.3.2.1): must pass to delivery component
        String fulfillmentId = null;
        String query = url.getQuery();
        if (query == null)
            throw new AdapterException("OTA", "JV-1200-008: The URL is missing the fid parameter: URL = "
                    + url.toString());

        String[] queryTokens = query.split("[&]");
        for (int i = 0; i < queryTokens.length; i++) {
            String token = queryTokens[i];
            if (token.startsWith("fid")) {
                String[] ids = token.split("=");
                fulfillmentId = ids[1];
            }
        }

        FulfillmentTask fulfillmentTask = adapterContext.getFulfillmentTask(fulfillmentId, null, "ota");
        BundleDescriptor bundleDescriptor = fulfillmentTask.getBundleDescriptor();

        if (bundleDescriptor == null)
            throw new AdapterException("OTA", "JV-1200-003: Could not locate the BundleDescriptor: FulfillmentID = "
                    + fulfillmentId);
        String baseUri = adapterConfig.getAdapterContext().getServletContext().getInitParameter("CONTENT_DELIVERY_URI")
                + adapterConfig.getBaseURI();
        String mediaUrl = baseUri + "?fid=" + fulfillmentId +"&type=media";

        OtaDescriptorFile descriptorFile = (OtaDescriptorFile) bundleDescriptor.getDescriptorFile();
        for(ProductType product : (List<ProductType>)descriptorFile.getMediaType().getProduct())
        {
            for(MediaObjectType mediaObject : (List<MediaObjectType>) product.getMediaObject())
            {
                List<String> servers = (List<String>) mediaObject.getObjectURI().getServer();
                servers.clear();
                servers.add(mediaUrl);
            }
        }
        //descriptorFile.setAppProperty();
        if (descriptorFile == null)
            throw new AdapterException("OTA", "JV-1200-004: Could not locate the DescriptorFile: FulfillmentID = "
                    + fulfillmentId);
        return descriptorFile;
    }

    //Used by the above method (so need to embed the fulfillmentID in the URL)
    public String createFulfillmentURI(FulfillmentTask fulfillmentTask) throws AdapterException {
        if (fulfillmentTask == null) throw new AdapterException("OTA", "JV-1200-007: FulfillmentTask is null");

        return adapterConfig.getAdapterContext().getServletContext().getInitParameter("CONTENT_DELIVERY_URI")
                + adapterConfig.getBaseURI() + "?fid=" + fulfillmentTask.getFulfillmentID();
    }

    protected void setAdapterConfig(AdapterConfig adapterConfig) {
        this.adapterConfig = adapterConfig;
    }
}
